package com.niiwoo.civet.user.service.local;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.niiwoo.civet.user.dao.entity.*;
import com.niiwoo.civet.user.dao.mapper.*;
import com.niiwoo.civet.user.dto.request.UserReportCircle;
import com.niiwoo.civet.user.dto.request.UserReportCreateRequestDTO;
import com.niiwoo.civet.user.enums.UserReportSourceEnum;
import com.niiwoo.tripod.base.utils.DateUtils;
import com.niiwoo.tripod.im.component.IMService;
import com.niiwoo.tripod.im.request.*;
import com.niiwoo.tripod.im.response.*;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 用户举报LocalService
 * @author zzl
 * @date 2018/1/24 21:37
 */
@Service
@Slf4j
public class UserReportLocalService {

    @Autowired
    private UserReportMapper userReportMapper;

    @Autowired
    SnowflakeIdWorker snowflakeIdWorker;

    @Autowired
    private UserBasicInfoMapperExt userBasicInfoMapper;

    @Autowired
    private IdentityInfoMapperExt identityInfoMapperExt;

    @Autowired
    private IMService imService;

    /**
     * 保存用户举报信息
     * @param userReportSaveRequestDTO
     */
    @Transactional(rollbackFor = Exception.class)
    public void createUserReport(UserReportCreateRequestDTO userReportSaveRequestDTO){
        UserReport userReport = cover(userReportSaveRequestDTO);
        userReportMapper.insertSelective(userReport);
    }

    /**
     * 转换及查询填充数据
     * @param userReportSaveRequestDTO
     * @return
     */
    private UserReport cover(UserReportCreateRequestDTO userReportSaveRequestDTO){
        UserReport userReport = new UserReport();
        userReport.setId(snowflakeIdWorker.nextId());
        Date now = new Date();
        userReport.setCreateTime(now);
        userReport.setUpdateTime(now);
        userReport.setReportReason(userReportSaveRequestDTO.getReportReason());
        userReport.setUserId(userReportSaveRequestDTO.getUserId());
        userReport.setReportImgUrl(JSONObject.toJSONString(userReportSaveRequestDTO.getReportImgUrl()));
        userReport.setReportSource(userReportSaveRequestDTO.getReportSource());
        userReport.setReportType(userReportSaveRequestDTO.getReportType());

        UserBasicInfo userBasicInfo = userBasicInfoMapper.selectByPrimaryKey(userReportSaveRequestDTO.getUserId());
        UserChatInfo loginUserChatInfo = new UserChatInfo();
        if(userBasicInfo!=null){
            userReport.setNickName(userBasicInfo.getNickName());
            userReport.setMobileNo(userBasicInfo.getMobileNo());
            userReport.setIdentityTag(userBasicInfo.getIdentityTag());
            loginUserChatInfo.userId=userReportSaveRequestDTO.getUserId();
            loginUserChatInfo.nickName=userBasicInfo.getNickName();
            loginUserChatInfo.headImage=userBasicInfo.getHeadImage();
        }

        IdentityInfo identityInfo = identityInfoMapperExt.selectByPrimaryKey(userReportSaveRequestDTO.getUserId());
        if(identityInfo != null){
            userReport.setName(identityInfo.getName());
        }

        initImInfo(userReportSaveRequestDTO, userReport, loginUserChatInfo);

        //如果被举报人userId不为空
        if(StringUtils.isNotBlank(userReport.getReportUserId())){
            UserBasicInfo userBasicInfoReport = userBasicInfoMapper.selectByPrimaryKey(userReport.getReportUserId());
            if(userBasicInfoReport != null){
                userReport.setReportNickName(userBasicInfoReport.getNickName());
                userReport.setReportMobileNo(userBasicInfoReport.getMobileNo());
                //产品设计要求群举报时，不显示群主角色
                if(!UserReportSourceEnum.SOURCE_2.getCode().equals(userReport.getReportSource())&&
                        !UserReportSourceEnum.SOURCE_3.getCode().equals(userReport.getReportSource())) {
                    userReport.setReportIdentityTag(userBasicInfoReport.getIdentityTag());
                }
            }

            IdentityInfo identityInfoReport = identityInfoMapperExt.selectByPrimaryKey(userReport.getReportUserId());
            if(identityInfoReport != null){
                userReport.setReportName(identityInfoReport.getName());
            }
        }

        return userReport;
    }

    /**
     * 查询并设置im相关的信息
     * @author zzl
     * @date 2018/1/23 11:21
     * @param userReportSaveRequestDTO, userReport
     * @return void
     */
    private void initImInfo(UserReportCreateRequestDTO userReportSaveRequestDTO, UserReport userReport, UserChatInfo loginUserChatInfo){
        if(userReport == null){
            return;
        }

        UserChatInfo reportUserChatInfo = null;
        if(StringUtils.isNotBlank(userReportSaveRequestDTO.getReportImid())){
            reportUserChatInfo = initReportUserId(userReportSaveRequestDTO, userReport);

            //设置被举报人信息
            JSONObject jsonObject = (JSONObject) JSONObject.toJSON(reportUserChatInfo);
            jsonObject.remove("imid");
            JSONArray array = new JSONArray();
            array.add(jsonObject);
            userReport.setReportGroupPersonnelInfo(array.toJSONString());
        }

        if(StringUtils.isNotBlank(userReportSaveRequestDTO.getReportGroupId())){
            userReport.setReportGroupId(userReportSaveRequestDTO.getReportGroupId());
            initReportGroupInfo(userReportSaveRequestDTO, userReport);
            initReportGroupMember(userReportSaveRequestDTO, userReport);
        }

        if(userReportSaveRequestDTO.getReportContent()!=null &&
                userReportSaveRequestDTO.getReportContent().size()>0){
            if(UserReportSourceEnum.SOURCE_1.getCode().equals(userReport.getReportSource())
                    ||UserReportSourceEnum.SOURCE_5.getCode().equals(userReport.getReportSource())){
                initSingleChatLog(userReportSaveRequestDTO, userReport, reportUserChatInfo, loginUserChatInfo);
            }else if(UserReportSourceEnum.SOURCE_2.getCode().equals(userReport.getReportSource())||
                    UserReportSourceEnum.SOURCE_3.getCode().equals(userReport.getReportSource())){
                initGroupChatLog(userReportSaveRequestDTO, userReport);
            }
        }

        if(UserReportSourceEnum.SOURCE_4.getCode().equals(userReport.getReportSource())){
            userReport.setReportContent(JSONObject.toJSONString(userReportSaveRequestDTO.getCircle()));
            //设置被举报人信息
            JSONObject jsonObject = (JSONObject) JSONObject.toJSON(reportUserChatInfo);
            jsonObject.remove("imid");
            JSONArray array = new JSONArray();
            array.add(jsonObject);
            userReport.setReportGroupPersonnelInfo(array.toJSONString());
        }

    }

    /**
     * 根据被举报人imid查询并设置userId
     * @param userReportSaveRequestDTO
     * @param userReport
     */
    private UserChatInfo initReportUserId(UserReportCreateRequestDTO userReportSaveRequestDTO, UserReport userReport){
        QueryImUserInfoRequest request = new QueryImUserInfoRequest();
        List<Long> imidList = new ArrayList<>();
        imidList.add(NumberUtils.toLong(userReportSaveRequestDTO.getReportImid()));
        request.setImid_list(imidList);
        try {
            CompletableFuture<QueryImUserInfoResponse> queryImUserInfoResponseCompletableFuture = imService.queryImUserInfo(request);
            QueryImUserInfoResponse response = queryImUserInfoResponseCompletableFuture.get();
            //返回码code: 1失败，0成功
            if (response != null && response.getCode() == 0) {
                if(response.getData() != null&&response.getData().size() > 0){
                    ImUserInfo imUserInfo = response.getData().get(0);
                    userReport.setReportUserId(imUserInfo.getBusinessId());
                    UserChatInfo userChatInfo = new UserChatInfo();
                    userChatInfo.headImage = imUserInfo.getAvatar();
                    userChatInfo.nickName = imUserInfo.getNickName();
                    userChatInfo.userId = imUserInfo.getBusinessId();
                    userChatInfo.imid = NumberUtils.toLong(userReportSaveRequestDTO.getReportImid());
                    log.info("queryImUserInfo成功: userId={}, imid = {}, response = {}", userReportSaveRequestDTO.getUserId(),userReportSaveRequestDTO.getReportImid(),response.getCode());
                    return userChatInfo;
                }
            }else{
                log.info("queryImUserInfo失败: userId={}, imid={}, response={}", userReportSaveRequestDTO.getUserId(),userReportSaveRequestDTO.getReportImid(),response.getCode());
                throw new BizException("USR19094");
            }
        } catch (Exception e) {
            log.error("queryImUserInfo异常: userId={}, imid={}, errorMessage={}",userReportSaveRequestDTO.getUserId(), userReportSaveRequestDTO.getReportImid(), e.getMessage(), e);
            throw new BizException("USR19094");
        }
        return null;
    }

    /**
     * 查询单聊聊天记录
     * @param userReportSaveRequestDTO
     * @param userReport
     */
    private void initSingleChatLog(UserReportCreateRequestDTO userReportSaveRequestDTO, UserReport userReport, UserChatInfo reportUserChatInfo, UserChatInfo loginUserChatInfo){
        JSONArray contentJsonArray = new JSONArray();
        for(String chatId: userReportSaveRequestDTO.getReportContent()){
            if(StringUtils.isBlank(userReportSaveRequestDTO.getReportImid())){
                break;
            }
            QuerySingleChatDetailRequest request = new QuerySingleChatDetailRequest();
            request.setMsgid(NumberUtils.toLong(chatId));
            request.setSelf_imid(NumberUtils.toLong(userReportSaveRequestDTO.getReportImid()));
            try {
                CompletableFuture<QuerySingleChatDetailResponse> future = imService.querySingleChatDetail(request);
                QuerySingleChatDetailResponse response = future.get();
                //返回码code: 1失败，0成功
                if (response != null && response.getCode() == 0) {
                    SingleChatDetail data = response.getData();
                    if(data == null){
                        log.info("querySingleChatDetail成功: userId={},imid={}, response={}", userReportSaveRequestDTO.getUserId(),userReportSaveRequestDTO.getReportImid(),response.getMsg());
                        continue;
                    }
                    UserReportContentTypeForChat chat = new UserReportContentTypeForChat();
                    chat.setMsgContent(data.getMsg());
                    chat.setMsgUrl(data.getMsg_url());
                    chat.setMsgId(String.valueOf(data.getMsgid()));
                    String date = coverAndFormatMsgTime(data.getMsg_time());
                    chat.setMsgTime(date);
                    chat.setMsgType(data.getMsg_type().byteValue());
                    if(data.getSend_imid().equals(reportUserChatInfo.imid)){
                        chat.setNickName(reportUserChatInfo.nickName);
                        chat.setHeadImage(reportUserChatInfo.headImage);
                        chat.setUserId(reportUserChatInfo.userId);
                    }else {
                        chat.setNickName(loginUserChatInfo.nickName);
                        chat.setHeadImage(loginUserChatInfo.headImage);
                        chat.setUserId(loginUserChatInfo.userId);
                    }
                    contentJsonArray.add(chat);
                    log.info("querySingleChatDetail成功: userId={},imid={}, response={}", userReportSaveRequestDTO.getUserId(),userReportSaveRequestDTO.getReportImid(),response);
                }else{
                    log.info("querySingleChatDetail失败: userId={},msgId={},imid={}, response={}", userReportSaveRequestDTO.getUserId(),chatId,userReportSaveRequestDTO.getReportImid(),response);
                }
            } catch (Exception e) {
                log.error("querySingleChatDetail异常: userId={},imid={}, errorMessage={}",userReportSaveRequestDTO.getUserId(), userReportSaveRequestDTO.getReportImid(), e.getMessage(), e);
            }
        }
        userReport.setReportContent(contentJsonArray.toJSONString());
    }

    private String coverAndFormatMsgTime(Long msgTime){
        return DateUtils.formatDate(new Date(msgTime*1000L),"yyyy-MM-dd HH:mm:ss");
    }


    /**
     * 查询群聊聊天记录
     * @param userReportSaveRequestDTO
     * @param userReport
     */
    private void initGroupChatLog(UserReportCreateRequestDTO userReportSaveRequestDTO, UserReport userReport){
        JSONArray contentJsonArray = new JSONArray();
        for(String chatId: userReportSaveRequestDTO.getReportContent()){
            QueryGroupChatDetailRequest request = new QueryGroupChatDetailRequest();
            request.setMsgid(NumberUtils.toLong(chatId));
            request.setGroup_id(NumberUtils.toLong(userReportSaveRequestDTO.getReportGroupId()));
            try {
                CompletableFuture<QueryGroupChatDetailResponse> future = imService.queryGroupChatDetail(request);
                QueryGroupChatDetailResponse response = future.get();
                //返回码code: 1失败，0成功
                if (response != null && response.getCode() == 0) {
                    GroupChatDetail data = response.getData();
                    if(data == null){
                        log.info("queryGroupChatDetail失败: userId={},imid={}, response={}", userReportSaveRequestDTO.getUserId(),userReportSaveRequestDTO.getReportImid(),response);
                        continue;
                    }
                    UserReportContentTypeForChat chat = new UserReportContentTypeForChat();
                    chat.setMsgContent(data.getMsg());
                    chat.setMsgUrl(data.getMsg_url());
                    chat.setMsgId(String.valueOf(data.getMsgid()));
                    String date = coverAndFormatMsgTime(data.getMsg_time());
                    chat.setMsgTime(date);
                    chat.setMsgType(data.getMsg_type().byteValue());
                    chat.setUserId(data.getSender_guid());
                    chat.setHeadImage(data.getSender_avatar());
                    chat.setNickName(data.getSender_nickname());
                    contentJsonArray.add(chat);
                    log.info("queryGroupChatDetail成功: userId={},imid={}, response={}", userReportSaveRequestDTO.getUserId(),userReportSaveRequestDTO.getReportImid(),response);
                }else{
                    log.info("queryGroupChatDetail失败: userId={},imid={}, response={}", userReportSaveRequestDTO.getUserId(),userReportSaveRequestDTO.getReportImid(),response);
                }
            } catch (Exception e) {
                log.error("queryGroupChatDetail异常: userId={},imid={}, errorMessage={}",userReportSaveRequestDTO.getUserId(), userReportSaveRequestDTO.getReportImid(), e.getMessage(), e);
            }
        }
        userReport.setReportContent(contentJsonArray.toJSONString());
    }

    /**
     * 查询被举报群信息
     * @param userReportSaveRequestDTO
     * @param userReport
     */
    private void initReportGroupInfo(UserReportCreateRequestDTO userReportSaveRequestDTO, UserReport userReport){

        //查询群信息
        userReport.setReportGroupId(userReportSaveRequestDTO.getReportGroupId());
        QueryGroupInfoRequest request = new QueryGroupInfoRequest();
        request.setGroup_id(NumberUtils.toLong(userReportSaveRequestDTO.getReportGroupId()));
        String groupOwnerUserId = null;
        try {
            CompletableFuture<QueryGroupInfoResponse> queryImUserInfoResponseCompletableFuture = imService.queryGroupInfo(request);
            QueryGroupInfoResponse response = queryImUserInfoResponseCompletableFuture.get();
            //返回码code: 1失败，0成功
            if (response != null && response.getCode() == 0) {
                if(response.getData() != null){
                    if(response.getData().getGroup_info()!=null) {
                        userReport.setReportGroupName(response.getData().getGroup_info().getGroup_name());
                        String groupCreateTime=response.getData().getGroup_info().getCreate_time();
                        if(StringUtils.isNotBlank(groupCreateTime)) {
                            Date groupCreateDate = DateUtils.parseDateFromString(groupCreateTime, "yyyy-MM-dd HH:mm:ss");
                            userReport.setReportGroupCreateTime(groupCreateDate);
                        }
                        userReport.setReportGroupPersonnelCount(response.getData().getGroup_info().getGroup_member_num());
                        groupOwnerUserId = response.getData().getGroup_info().getGuid();
                        log.info("queryGroupInfo成功: userId={}, groupId = {}, response = {}", userReportSaveRequestDTO.getUserId(), userReportSaveRequestDTO.getReportGroupId(), response);
                    }
                }
            }else{
                log.info("queryGroupInfo失败: userId={}, groupId={}, response={}", userReportSaveRequestDTO.getUserId(),userReportSaveRequestDTO.getReportGroupId(),response);
                throw new BizException("USR19094");
            }
        } catch (Exception e) {
            log.error("queryGroupInfo异常: userId={}, groupId={}, errorMessage={}",userReportSaveRequestDTO.getUserId(), userReportSaveRequestDTO.getReportGroupId(), e.getMessage(), e);
            throw new BizException("USR19094");
        }

        //群举报时，设置群主信息到被举报人
        if(StringUtils.isNotBlank(groupOwnerUserId)){
            if(StringUtils.isBlank(userReport.getReportUserId())){
                log.debug("被举报的群主userId:"+groupOwnerUserId);
                userReport.setReportUserId(groupOwnerUserId);
            }
        }
    }

    /**
     * 查询被举报群成员列表
     * @param userReportSaveRequestDTO
     * @param userReport
     */
    private void initReportGroupMember(UserReportCreateRequestDTO userReportSaveRequestDTO, UserReport userReport){
        String groupOwnerUserId = null;
        try {
            QueryGroupMemberRequest request = new QueryGroupMemberRequest();
            request.setGroup_id(NumberUtils.toLong(userReportSaveRequestDTO.getReportGroupId()));
            CompletableFuture<QueryGroupMemberResponse> queryGroupMemberResponseCompletableFuture = imService.queryGroupMember(request);
            QueryGroupMemberResponse response = queryGroupMemberResponseCompletableFuture.get();
            //返回码code: 1失败，0成功
            if (response != null && response.getCode() == 0) {
                if(response.getData() != null){
                    if(response.getData().getGroup_member_list()!=null) {
                        JSONArray jsonArray=new JSONArray();
                        for(QueryGroupMemberResponse.GroupMember member: response.getData().getGroup_member_list()){

                            JSONObject user = new JSONObject();
                            //see:com.niiwoo.civet.manage.web.vo.response.user.UserReportGroupPersonnelInfoRespVO
                            user.put("userId",member.getGuid());
                            user.put("nickName",member.getNick_name());
                            user.put("headImage",member.getAvatar());
                            jsonArray.add(user);
                        }
                        userReport.setReportGroupPersonnelInfo(jsonArray.toJSONString());

                        log.info("queryGroupMember成功: userId={}, groupId = {}, response = {}", userReportSaveRequestDTO.getUserId(), userReportSaveRequestDTO.getReportGroupId(), response.getCode());
                    }
                }
            }else{
                log.info("queryGroupMember失败: userId={}, groupId={}, response={}", userReportSaveRequestDTO.getUserId(),userReportSaveRequestDTO.getReportGroupId(),response.getCode());
                throw new BizException("USR19094");
            }
        } catch (Exception e) {
            log.error("queryGroupMember异常: userId={}, groupId={}, errorMessage={}",userReportSaveRequestDTO.getUserId(), userReportSaveRequestDTO.getReportGroupId(), e.getMessage(), e);
            throw new BizException("USR19094");
        }
    }

    /**
     * 仅本类中方法使用临时数据对象:用户聊天时的用户信息
     */
    @Getter
    @Setter
    private class UserChatInfo{
        /**
         * 用户 id
         */
        private String userId;

        /**
         * 昵称
         */
        private String nickName;

        /**
         * 头像
         */
        private String headImage;

        /**
         * 用户imid
         */
        private Long imid;
    }

}
